<?php

class sfValidatorDoctrineTagsInput extends sfValidatorBase
{
    protected function configure($options = array(), $messages = array())
    {
        $this->addRequiredOption('model');
        $this->addOption('query', null);
        $this->addOption('column', null);
        $this->addOption('multiple', false);
        $this->addOption('min');
        $this->addOption('max');

        $this->addMessage('min', 'At least %min% values must be selected (%count% values selected).');
        $this->addMessage('max', 'At most %max% values must be selected (%count% values selected).');
    }
    /**
     * @see sfValidatorBase
     */
    protected function doClean($value)
    {

        if (!is_array($value))
        {
          $value = explode(',',$value);
        }

        if (isset($value[0]) && !$value[0])
        {
          unset($value[0]);
        }

        $count = count($value);

        if ($this->hasOption('min') && $count < $this->getOption('min'))
        {
          throw new sfValidatorError($this, 'min', array('count' => $count, 'min' => $this->getOption('min')));
        }

        if ($this->hasOption('max') && $count > $this->getOption('max'))
        {
          throw new sfValidatorError($this, 'max', array('count' => $count, 'max' => $this->getOption('max')));
        }

        foreach($value as $tag){

            if ($query = $this->getOption('query'))
            {
                $query = clone $query;
            }
            else
            {
                $query = Doctrine_Core::getTable($this->getOption('model'))->createQuery();
            }

            $query->andWhere(sprintf('%s.%s = ?', $query->getRootAlias(), $this->getColumn()), $tag);

            if ($query->count() != 1)
            {
                $type = $this->getOption('model');
                $new_tag = new $type;
                call_user_func_array(array($new_tag,'set'.$this->getColumn()),array($tag));
                $new_tag->save();
            }
        }

        return $value;
    }

  /**
   * Returns the column to use for comparison.
   *
   * The primary key is used by default.
   *
   * @return string The column name
   */
  protected function getColumn()
  {
    $table = Doctrine_Core::getTable($this->getOption('model'));
    if ($this->getOption('column'))
    {
      $columnName = $this->getOption('column');
    }
    else
    {
      $identifier = (array) $table->getIdentifier();
      $columnName = current($identifier);
    }

    return $table->getColumnName($columnName);
  }
}
